package com.gmall.security.filter;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gmall.common.constant.Constant;
import com.gmall.common.model.Response;
import com.gmall.common.util.JwtUtil;
import com.gmall.security.vo.JwtUser;
import com.gmall.user.api.po.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
*
 * @author HL.Wu
 * @date 2020/5/22 13:31
 * Copyright ©https://blog.csdn.net/qq_31150503 Copyright@2009-2020 AII Right Reserve
 */
@Slf4j
public class LoginAuthFilter extends UsernamePasswordAuthenticationFilter {

    private AuthenticationManager authenticationManager;

    public LoginAuthFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
        super.setFilterProcessesUrl("/user/login");
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        try {
            // 获取用户登录信息
            User user = new ObjectMapper().readValue(request.getInputStream(), User.class);
            // 校验信息
            return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword(),new ArrayList<>()));
        } catch (IOException e) {
            return null;
        }
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        //  校验成功
        // 获取登录用户信息详情
        JwtUser jwtUser = (JwtUser) authResult.getPrincipal();
        // 是否勾选记住登录状态
        String rememberMe = request.getParameter("isRememberMe");
        boolean isRememberMe = false;
        if(StrUtil.isNotBlank(rememberMe) && String.valueOf(1).compareTo(rememberMe) == 0){
            isRememberMe = true;
        }
        // 获取用户角色
        Collection<? extends GrantedAuthority> authorities = jwtUser.getAuthorities();
        List<String> roleList = new ArrayList<>();
        Optional.ofNullable(authorities).ifPresent(roles -> roles.stream().forEach(role -> roleList.add(role.getAuthority())));
        // 获取Token
        Map<String, Object> map = new HashMap<>();
        // user role info put play load
        map.put("ROLE_CLAIMS",roleList);
        map.put(Constant.REMEMBER_ME,isRememberMe);
        map.put(Constant.COMPANY_ID,jwtUser.getCompanyId());
        String token = JwtUtil.createToken(jwtUser.getId(),jwtUser.getUsername(),map);
        log.info("current login user info is: \n [{}] \n token is [{}]",jwtUser,token);
        // 返还相应token
        response.setHeader(JwtUtil.TOKEN_HEADER,JwtUtil.TOKEN_PREFIX + token);
        response.setHeader("Access-Control-Expose-Headers", JwtUtil.TOKEN_HEADER);
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        //  校验失败
        Response resp = CoreAuthFilter.authExceptionHandle(failed);
        response.getWriter().write(JSON.toJSONString(resp));
    }
}
